package com.hcloud.common.crud.controller;

import com.hcloud.audit.core.annontion.BaseOperateLog;
import com.hcloud.audit.core.util.OperateType;
import com.hcloud.common.core.base.BaseBean;
import com.hcloud.common.core.base.HCloudResult;
import com.hcloud.common.core.constants.AuthConstants;
import com.hcloud.common.crud.annon.HCloudPreAuthorize;
import com.hcloud.common.crud.service.BaseDataService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * T 实体对象
 * Q 查询时的对象，继承自T，扩展查询参数
 *
 * @Auther hepangui
 * @Date 2018/11/2
 */
public abstract class BaseDataController<T extends BaseBean, Q extends T> {
    protected abstract BaseDataService getBaseDataService();

    /**
     * 获取一个VO对象
     *
     * @param id
     * @return
     */
    @GetMapping("/get/{id}")
    @HCloudPreAuthorize(AuthConstants.SEE)
    @BaseOperateLog(type = OperateType.QUERY)
    public HCloudResult getOne(@PathVariable String id) {
        var baseBean = getBaseDataService().getBean(id);
        if (baseBean == null) {
            return new HCloudResult("实体不存在");
        }
        return new HCloudResult(baseBean);
    }

    @DeleteMapping("/delete/{id}")
    @HCloudPreAuthorize(AuthConstants.DEL)
    @BaseOperateLog(type = OperateType.DEL)
    public HCloudResult deleteOne(@PathVariable String id) {
        var baseBean = getBaseDataService().getBean(id);
        if (baseBean == null) {
            return new HCloudResult("实体不存在");
        }
        getBaseDataService().deleteById(id);
        return new HCloudResult();

    }

    @PostMapping("/add")
    @HCloudPreAuthorize(AuthConstants.ADD)
    @BaseOperateLog(type = OperateType.ADD)
    public HCloudResult saveOne(@Valid T bean) {
        if (bean == null) {
            return new HCloudResult("参数有误");
        }
        if (bean.getId() != null && !"".equals(bean.getId())) {
            return new HCloudResult("添加时不允许有id");
        }
        getBaseDataService().add(bean);
        return new HCloudResult();
    }

    /**
     * 在url上就分开add与update 防止在想要update的时候执行了add操作却不知情
     *
     * @param bean
     * @return
     */
    @PostMapping("/update")
    @HCloudPreAuthorize(AuthConstants.EDIT)
    @BaseOperateLog(type = OperateType.UPDATE)
    public HCloudResult updateOne(@Valid T bean) {
        if (bean == null || bean.getId() == null || "".equals(bean.getId())
                || getBaseDataService().get(bean.getId()) == null) {
            return new HCloudResult("参数有误");
        }
        getBaseDataService().update(bean);
        return new HCloudResult();

    }

    /**
     * 按条件分页查询
     *
     * @param page
     * @param sortProperties
     * @param direction
     * @param queryBean
     * @return
     */
    @PostMapping("/list")
    @HCloudPreAuthorize(AuthConstants.SEE)
    @BaseOperateLog(type = OperateType.QUERY)
    public HCloudResult list(Integer page, Integer limit,
                             String sortProperties, String direction, Q queryBean) {
        Sort sort = null;
        if (direction != null && !"".equals(direction)
                && sortProperties != null && !"".equals(sortProperties)) {
            String[] split = sortProperties.split(",");
            if ("asc".equals(direction)) {
                sort = new Sort(Sort.Direction.ASC, split);
            } else {
                sort = new Sort(Sort.Direction.DESC, split);
            }
        }
        if (page == null || limit == null || limit.equals(-1)) {
            List byCondition = null;
            if (sort == null) {
                byCondition = this.getBaseDataService().findByCondition(queryBean);
            } else {
                return new HCloudResult(this.getBaseDataService().findByCondition(queryBean, sort));
            }
            if (byCondition != null) {
                return new HCloudResult(byCondition, byCondition.size());
            } else {
                return new HCloudResult(new ArrayList<>(), 0);
            }
        } else {
            Pageable pageable;
            page = page - 1;
            if (sort != null) {
                pageable = PageRequest.of(page, limit, sort);
            } else {
                pageable = PageRequest.of(page, limit);
            }
            Page byCondition = this.getBaseDataService().findByCondition(pageable, queryBean);
            return new HCloudResult(byCondition.getContent(), byCondition.getTotalElements());
        }
    }

}
